package org.x.usermod.service.impl;

import com.mybatisflex.core.query.QueryWrapper;
import org.x.commonmod.config.Result;
import org.x.usermod.dto.AssignAclsDTO;
import org.x.usermod.dto.AssignRolesDTO;

import org.x.usermod.dto.UserAclDTO;
import org.x.usermod.entity.*;
import org.x.usermod.mapper.*;
import org.x.usermod.service.IAuthManagementService;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class AuthManagementServiceImpl implements IAuthManagementService {
    private final SysUserMapper sysUserMapper;
    private final SysRoleMapper sysRoleMapper;
    private final SysRoleUserMapper sysRoleUserMapper;
    private final SysRoleAclMapper sysRoleAclMapper;
    private final SysAclMapper sysAclMapper;
    private final SysRoleUserMapper sysRoleUser;
    private final SysMenuMapper sysMenuMapper;
    private final SysMenuMapper sysMenu;


    public AuthManagementServiceImpl(SysUserMapper sysUserMapper, SysRoleMapper sysRoleMapper, SysRoleUserMapper sysRoleUserMapper, SysRoleAclMapper sysRoleAclMapper, SysAclMapper sysAclMapper, SysRoleUserMapper sysRoleUser, SysMenuMapper sysMenuMapper, SysMenuMapper sysMenu) {
        this.sysUserMapper = sysUserMapper;
        this.sysRoleMapper = sysRoleMapper;
        this.sysRoleUserMapper = sysRoleUserMapper;
        this.sysRoleAclMapper = sysRoleAclMapper;
        this.sysAclMapper = sysAclMapper;
        this.sysRoleUser = sysRoleUser;
        this.sysMenuMapper = sysMenuMapper;
        this.sysMenu = sysMenu;
    }

    @Override
    public Result assignRole(AssignRolesDTO assignRolesDTO) {
        // 1.根据用户id查询用户
        SysUser user = sysUserMapper.selectOneById(assignRolesDTO.getUserId());
        if (user == null) {
            return Result.fail("404", "用户不存在");
        }
        // 2.根据角色id查询角色
        List<SysRole> sysRoles = sysRoleMapper.selectListByIds(Arrays.asList(assignRolesDTO.getRoleIds()));
        if (sysRoles.isEmpty()) {
            return Result.fail("404", "角色不存在");
        }
        // 3.循环角色分配
        for (SysRole sysRole : sysRoles) {
            SysRoleUser sysRoleUser = new SysRoleUser();
            sysRoleUser.setUserId(assignRolesDTO.getUserId());
            sysRoleUser.setRoleId(sysRole.getId());
            sysRoleUser.setCreatedTime(new Date());
            sysRoleUserMapper.insert(sysRoleUser);
        }

        return Result.ok("用户角色分配成功");
    }

    @Override
    public Result assignAcl(AssignAclsDTO assignAclsDTO) {
        // 1.根据角色id查询角色
        SysRole role = sysRoleMapper.selectOneById(assignAclsDTO.getRoleId());
        if (role == null) {
            return Result.fail("404", "角色不存在");
        }
        // 2.根据权限id查询权限
        List<SysAclEntity> sysAcls = sysAclMapper.selectListByIds(Arrays.asList(assignAclsDTO.getAclIds()));
        if (sysAcls.isEmpty()) {
            return Result.fail("404", "权限不存在");
        }
        // 3.循环权限分配
        for (SysAclEntity sysAcl : sysAcls) {
            SysRoleAcl sysRoleAcl = new SysRoleAcl();
            sysRoleAcl.setRoleId(assignAclsDTO.getRoleId());
            sysRoleAcl.setAclId(sysAcl.getId());
            sysRoleAcl.setCreatedTime(new Date());
            sysRoleAclMapper.insert(sysRoleAcl);
        }

        return Result.ok("用户角色分配成功");
    }
    @Override
    public UserAclDTO userPermissions(Long userId) {
        // 1. 初始化DTO（只创建一次）
        UserAclDTO userAclDTO = new UserAclDTO();
        userAclDTO.setUserId(userId);  // 设置用户ID

        // 2. 验证用户存在
        SysUser user = sysUserMapper.selectOneById(userId);
        if (user == null) {
            throw new IllegalArgumentException("用户不存在");
        }

        // 3. 构建角色信息
        List<SysRoleUser> roleUsers = sysRoleUserMapper.selectListByQuery(
                QueryWrapper.create().eq(SysRoleUser::getUserId, userId)
        );

        if (!roleUsers.isEmpty()) {
            List<UserAclDTO.RolesInfo> rolesList = roleUsers.stream()
                    .map(roleUser -> {
                        UserAclDTO.RolesInfo roleInfo = new UserAclDTO.RolesInfo();
                        roleInfo.setRoleId(roleUser.getRoleId());

                        SysRole role = sysRoleMapper.selectOneById(roleUser.getRoleId());
                        if (role != null) {
                            roleInfo.setName(role.getName());
                            roleInfo.setCode(role.getCode());
                        }
                        return roleInfo;
                    })
                    .collect(Collectors.toList());
            userAclDTO.setRoles(rolesList);
        }

        // 4. 构建权限信息（基于所有角色）
        if (userAclDTO.getRoles() != null && !userAclDTO.getRoles().isEmpty()) {
            List<Long> roleIds = userAclDTO.getRoles().stream()
                    .map(UserAclDTO.RolesInfo::getRoleId)
                    .collect(Collectors.toList());

            List<SysRoleAcl> roleAcls = sysRoleAclMapper.selectListByQuery(
                    QueryWrapper.create()
                            .in(SysRoleAcl::getRoleId, roleIds)
                            .select("DISTINCT acl_id")
            );

            if (!roleAcls.isEmpty()) {
                List<UserAclDTO.AclInfo> aclInfoList = roleAcls.stream()
                        .map(roleAcl -> {
                            UserAclDTO.AclInfo aclInfo = new UserAclDTO.AclInfo();
                            aclInfo.setAclId(roleAcl.getAclId());

                            SysAclEntity acl = sysAclMapper.selectOneById(roleAcl.getAclId());
                            if (acl != null) {
                                aclInfo.setName(acl.getName());
                                aclInfo.setCode(acl.getCode());
                            }
                            return aclInfo;
                        })
                        .collect(Collectors.toList());
                userAclDTO.setPermissions(aclInfoList);
            }
        }

        // 5. 构建菜单树（使用同一个DTO对象）
        List<SysMenu> allMenus = sysMenuMapper.selectListByQuery(
                QueryWrapper.create()
                        .where("is_delete = ?", 0)
                        .orderBy("sort ASC")
        );

        List<UserAclDTO.MenuTree> menuTrees = new ArrayList<>();

        // 处理无acl的菜单
        allMenus.stream()
                .filter(menu -> menu.getAclId() == null)
                .forEach(menu -> menuTrees.add(convertToMenuTree(menu)));

        // 构建树形结构
        allMenus.stream()
                .filter(menu -> menu.getParentId() == 0 && menu.getAclId() != null)
                .forEach(rootMenu -> {
                    UserAclDTO.MenuTree rootTree = convertToMenuTree(rootMenu);
                    List<UserAclDTO.MenuTree> children = allMenus.stream()
                            .filter(menu -> rootMenu.getId().equals(menu.getParentId()))
                            .map(this::convertToMenuTree)
                            .collect(Collectors.toList());

                    if (!children.isEmpty()) {
                        rootTree.setChildren(children);
                    }
                    menuTrees.add(rootTree);
                });

        userAclDTO.setMenuTree(menuTrees);
        return userAclDTO;
    }

    // 辅助方法：将SysMenu转换为MenuTree
    private UserAclDTO.MenuTree convertToMenuTree(SysMenu menu) {
        UserAclDTO.MenuTree menuTree = new UserAclDTO.MenuTree();
        menuTree.setMenuId(menu.getId());
        menuTree.setName(menu.getName());
        menuTree.setPath(menu.getPath());
        return menuTree;
    }

}
